package com.lzkjiot.service.gnss.transger.core.transfer.gnssdata;

import com.lzkjiot.service.gnss.transger.core.client.SiNanClientPoolManager;
import com.lzkjiot.service.gnss.transger.core.client.TestClientPoolManager;
import com.lzkjiot.service.gnss.utils.BitUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class GnssRTCMDataTransferWorker implements Runnable{

    private static final byte PREAMBLE = (byte) 0xd3;		// 8bits
    private static final byte RESERVED = (byte) 0x00;		// upper6bits
    private static final int CRCBYTELENGTH = 3;			    // 24bits CRC length
    private static final int HEADERBYTELENGTH = 3;		    // 24bits
    private static final int CRC24_POLY  = 0x1864CFB;

    private int port;
    private byte[] frameData;

    public GnssRTCMDataTransferWorker(int port, byte[] frameData) {
        this.port = port;
        this.frameData = frameData;
    }

    @Override
    public void run() {
        try{
            System.out.println("[RtcmTransWorker] To port "+ port + " datalen:" + frameData.length);
            byte[] destination = new byte[frameData.length];
            System.arraycopy(frameData, 0, destination, 0, frameData.length);
            SiNanClientPoolManager.pushGnssData(port, frameData);
            if(port == 60440 || port == 60443){
                TestClientPoolManager.pushGnssData(port-40000, destination);
            }
        } catch (Exception ex){

            System.err.println("[RtcmTransWorker] To port "+ port + " exception:" + ex.getMessage());
        }

    }
    // 发送RTCM数据到指定端口 附带RTCM校验
    private void sendData(int port, byte[] data){
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        for (int index = 0; index < data.length;) {
            // 校验帧起始标识符
            if (frameData[index] == (byte) PREAMBLE && (frameData[index + 1] & 0xfc) >> 2 == RESERVED) {
                // 解析帧长度
                int frameLength = BitUtils.bitToInt(frameData, (index * 8) + 14, 10);
                byte[] rtcmFrame = new byte[frameLength + 6];
                System.arraycopy(frameData, index, rtcmFrame, 0, frameLength + 6);
                index += (frameLength + 6);
                int targetCRC = BitUtils.bitToInt(rtcmFrame, (rtcmFrame.length - CRCBYTELENGTH) * 8, CRCBYTELENGTH * 8);
                int calcCrc = calcCrc(rtcmFrame);
                // 检查校验和是否正确
                if (targetCRC == calcCrc) {
                    try {
                        outputStream.write(rtcmFrame);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        byte[] rtcmData = outputStream.toByteArray();
        if(rtcmData.length > 0){
            SiNanClientPoolManager.pushGnssData(port, rtcmData);
        }
    }
    private static int calcCrc(byte[] bytes) {
        int crc = 0;
        for(int i = 0; i < bytes.length - CRCBYTELENGTH; i++) {
            crc ^= bytes[i] << 16;
            for(int j= 0; j < 8; j++) {
                crc <<= 1;
                if((crc & 0x1000000) != 0) {
                    crc ^= CRC24_POLY;
                }
            }
        }
        return crc;
    }

    public static String bytesToHexString(byte[] bytes) {
        StringBuilder hexString = new StringBuilder();
        for (byte b : bytes) {
            // 使用 String.format 方法将每个字节转换为十六进制字符串
            hexString.append(String.format("%02X", b));
        }
        return hexString.toString();
    }

    public static String printBinary(byte[] bytes) {
        StringBuilder binaryString = new StringBuilder();
        for (byte b : bytes) {
            // 使用 Integer.toBinaryString 方法将每个字节转换为二进制字符串，并在前面补足0使长度为8位
            binaryString.append(String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0'));
        }
        return binaryString.toString();
    }

}
